import os

from django.shortcuts import get_object_or_404
from rest_framework.decorators import action
from rest_framework.permissions import IsAuthenticated
from rest_framework import  status
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet

from common.pagination import TenPerPageNumberPagination
from performance.export import export_excel
from performance.models import server, presetting, PerformanceTask, TaskScence, TaskStep, TaskScenceStep
from performance.serializers import ServerSerializer, PresettingSerializer, PerformanceTaskSerializer, \
    TaskScenceSerializer, ScenceStepSerializer, TaskScenceStepSerializer
from projects.models import newInterface
from projects.serializers import newInterfaceSerializer
from performanceengine import main

class ServerViewSet(ModelViewSet):
    """服务器视图集"""
    queryset = server.objects.all()
    serializer_class = ServerSerializer
    permission_classes = [IsAuthenticated]
    filterset_fields = ['name']
    pagination_class = TenPerPageNumberPagination

    def get_queryset(self):
        queryset = super().get_queryset()
        # 获取参数
        project = self.request.query_params.get('project_id')
        # 过滤
        if project:
            queryset = queryset.filter(project_id=project)

        return queryset


class PresettingViewSet(ModelViewSet):
    """预置配置视图集"""
    queryset = presetting.objects.all().order_by('-create_time')
    serializer_class = PresettingSerializer
    permission_classes = [IsAuthenticated]
    filterset_fields = ['name', 'task', 'isSetting', 'taskType']
    pagination_class = TenPerPageNumberPagination


    @action(methods=['post'], detail=False)
    def save_presetting(self, request, *args, **kwargs):
        global data, task
        if 'task' in request.data:
            data = request.data
            data['isSetting'] = True
            task = self.request.data.get('task')
        else:
            return Response({"message": "请确认传参完整后再重试"}, status=status.HTTP_400_BAD_REQUEST)

        is_presetting = self.queryset.filter(task_id=task).first()

        if is_presetting:
            serializer = self.get_serializer(is_presetting, data=data, partial=True)  # partial=True 允许部分更新
            if serializer.is_valid():
                serializer.save()
                return Response(serializer.data, status=status.HTTP_200_OK)
            return Response({"message": serializer.errors}, status=status.HTTP_400_BAD_REQUEST)
        else:
            serializer = self.get_serializer(data=data)
            if serializer.is_valid():
                serializer.save()
                return Response(serializer.data, status=status.HTTP_200_OK)
            return Response({"message": serializer.errors}, status=status.HTTP_400_BAD_REQUEST)





    def get_queryset(self):
        queryset = super().get_queryset()
        # 获取参数
        project = self.request.query_params.get('project_id')
        # 过滤
        if project:
            queryset = queryset.filter(project_id=project)

        return queryset




class PerformanceTaskViewSet(ModelViewSet):
    """性能任务视图集"""
    queryset = PerformanceTask.objects.all().order_by('-create_time')
    serializer_class = PerformanceTaskSerializer
    permission_classes = [IsAuthenticated]
    filterset_fields = ['taskName']
    pagination_class = TenPerPageNumberPagination

    def get_queryset(self):
        queryset = super().get_queryset()
        # 获取参数
        project = self.request.query_params.get('project_id')
        # 过滤
        if project:
            queryset = queryset.filter(project_id=project)

        return queryset

    @action(methods=['post'], detail=True)
    def run(self, request, pk):
        task = get_object_or_404(PerformanceTask, id=pk)
        if not task.taskScence.exists():
            return Response({'message': '该任务下无性能测试场景，请添加后再试'}, status=status.HTTP_400_BAD_REQUEST)

        # 1. 获取环境id
        env_id = request.data.get('env')
        # 2. 生成测试结果
        # serializer = RecordSerializer(data={
        #     'test_env': env_id,
        #     'plan': pk,
        #     'status': '执行中',
        #     'tester': request.user.username,
        #     'project': plan.project_id,
        #     'execute_type': '手动执行'
        # })
        # serializer.is_valid(raise_exception=True)
        # record = serializer.save()
        # 同步执行测试计划
        if os.environ.get('ENV') == 'production':
            # 异步执行
            main.run_task.delay(pk, env_id)
        else:
            main.run_task(pk, env_id)
        return Response({'message': '执行成功'})

class TaskScenceViewSet(ModelViewSet):
    """性能场景视图集"""
    queryset = TaskScence.objects.all()
    serializer_class = TaskScenceSerializer
    permission_classes = [IsAuthenticated]
    filterset_fields = ['name', 'task']

    @action(methods=['get'], detail=False)
    def export(self, request, *args, **kwargs):
        queryset = TaskScence.objects.all()
        data = []
        row_one = ['场景名称', '性能任务名称', '环境名称', '权重', '创建时间']
        for obj in queryset:
            task_name = obj.task.taskName if obj.task else ''
            env_name = obj.env.name if obj.env else ''
            scene_name = obj.name
            weight = obj.weight
            create_time = obj.create_time.strftime('%Y-%m-%d %H:%M:%S') if obj.create_time else ''

            data.append([scene_name, task_name, env_name, weight, create_time])
        return export_excel('性能场景', row_one, data)


class ScenceSetpViewSet(ModelViewSet):
    """步骤视图集"""
    queryset = TaskStep.objects.all()
    serializer_class = ScenceStepSerializer
    permission_classes = [IsAuthenticated]
    filterset_fields = ['type','scence']

    def create(self, request, *args, **kwargs):
        data = request.data

        if isinstance(data, list):
            objs = []
            if isinstance(data, list):
                for item in data:
                    scence_id = int(item.get('scence'))
                    if scence_id is not None :
                        del item['scence']
                        scence = TaskScence.objects.get(pk=scence_id)
                        obj = TaskStep(scence=scence,**item)
                        objs.append(obj)

                TaskStep.objects.bulk_create(objs)
                created_objs = TaskStep.objects.filter(scence__in=[obj.scence.id for obj in objs]).order_by('-id')[:len(objs)]
                # 序列化创建的对象
                serialized_data = ScenceStepSerializer(created_objs, many=True).data
                return Response(serialized_data, status=status.HTTP_201_CREATED)

        return super().create(request, *args, **kwargs)

    @action(methods=['post'], detail=False)
    def batchSaveSetp(self, request, *args, **kwargs):
        try:
            data = request.data
            if not isinstance(data, list):
                return super().update(request, *args, **kwargs)

            # 定义递归函数来处理children中的数据
            def process_children(data):
                for item in data:
                    step_info = item.get('stepInfo', None)
                    if step_info:
                        id = step_info.get('id', None)
                        item['stepInfo'].pop('inputDlg', None)
                        item['stepInfo'].pop('dlg', None)

                        instance = TaskStep.objects.get(id=id)
                        serializer = ScenceStepSerializer(instance, data=step_info, partial=True)
                        if serializer.is_valid():
                            serializer.save()
                        else:
                            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

                    if item:
                        id = item.get('id', None)
                        item.pop('stepInfo')
                        instances = TaskScenceStep.objects.get(id=id)
                        serializer = TaskScenceStepSerializer(instances, data=item, partial=True)
                        if serializer.is_valid():
                            serializer.save()
                        else:
                            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


                    # 递归处理children
                    children = item.get('children', [])
                    if children:
                        process_children(children)

            # 调用递归函数处理数据
            process_children(data)

            return Response(request.data, status=status.HTTP_200_OK)

        except Exception as e:
            return Response({'message': str(e)}, status=status.HTTP_400_BAD_REQUEST)

    @action(methods=['post'], detail=False)
    def batchSaveApiSetp(self, request, *args, **kwargs):
        data = request.data
        response_data = []
        for item in data:
            step_id = item.get('id', None)
            interface_id = item.get('content').get('id', None)
            if not step_id or not interface_id:
                return Response({'message': '缺失step_id or interface_id'}, status=status.HTTP_400_BAD_REQUEST)
            try:
                step_instance = TaskStep.objects.get(id=step_id)
                interface_instance = newInterface.objects.get(id=interface_id)
                serializer = newInterfaceSerializer(interface_instance).data
                step_instance.content = serializer
                step_instance.save()

                step_serializer = ScenceStepSerializer(step_instance)
                response_data.append(step_serializer.data)

            except Exception as e:
                return Response({'message': str(e)}, status=status.HTTP_400_BAD_REQUEST)
        return Response({'data': response_data}, status=status.HTTP_200_OK)

class TaskScenceStepViewSet(ModelViewSet):
    """性能任务场景步骤视图集"""
    queryset = TaskScenceStep.objects.all()
    serializer_class = TaskScenceStepSerializer
    filterset_fields = ['scence']
    permission_classes = [IsAuthenticated]

    def get_queryset(self):
        queryset = TaskScenceStep.objects.all().filter(parent_id=None).order_by('sort')
        scence = self.request.query_params.get('scence', None)
        if scence is None or scence == '':
            return TaskScenceStep.objects.none()
        return queryset.filter(scence=scence)
    def create(self, request, *args, **kwargs):
        data = request.data
        steps = request.data.get('step', None)
        if isinstance(steps, list):
            sort_value = request.data.get('sort', None)
            objs = []
            scence = TaskScence.objects.get(pk=int(data['scence']))
            task = PerformanceTask.objects.get(pk=int(data['task']))
            params = {
                'step': None,
                'scence': scence,
                'task': task,
                'sort': None,
                'parent': request.data.get('parent', None),
                'creator': request.data.get('creator', None)
            }
            for index, step in enumerate(steps):
                params['step'] = TaskStep.objects.get(pk=step)
                params['sort'] = sort_value if index == 0 else sort_value + index

                obj = TaskScenceStep(**params)
                objs.append(obj)
            TaskScenceStep.objects.bulk_create(objs)
            created_objs = TaskScenceStep.objects.filter(scence__in=[obj.scence.id for obj in objs]).order_by('-id')[:len(objs)]
            serialized_data = TaskScenceStepSerializer(created_objs, many=True).data
            return Response(serialized_data, status=status.HTTP_201_CREATED)
        return super().create(request, *args, **kwargs)

    def destroy(self, request, pk=None):
        try:
            instance = TaskScenceStep.objects.get(pk=pk)
            if instance.parent_id:
                if TaskScenceStep.objects.filter(parent=instance.id).exists():
                    return Response({"message": "存在未删除的子节点，请先删除子节点后再操作"}, status=status.HTTP_400_BAD_REQUEST)
                TaskScenceStep.objects.filter(id=instance.id).delete()
            else:
                if TaskScenceStep.objects.filter(parent=instance.id).exists():
                    return Response({"message": "存在未删除的子节点，请先删除子节点后再操作"}, status=status.HTTP_400_BAD_REQUEST)
                instance.delete()
            return Response({"message": "操作成功"},status=status.HTTP_204_NO_CONTENT)

        except TaskScenceStep.DoesNotExist:
            return Response(status=status.HTTP_404_NOT_FOUND)

    @action(methods=['post'], detail=False)
    def batchTaskScenceStep(self, request, *args, **kwargs):
        try:
            data = request.data.get('data')
            type = request.data.get('type')
            response_data = []
            # 定义递归函数来处理children中的数据
            def process_children(data):
                for item in data:
                    step_info = item.get('stepInfo', None)
                    if step_info:
                        id = step_info.get('id', None)
                        lord_id = item.get('id', None)
                        if type == 'start':
                            instance = TaskStep.objects.get(id=id)
                            instance.status = True
                            instance.save()
                            response_data.append(ScenceStepSerializer(instance).data)

                        elif type == 'stop':
                            instance = TaskStep.objects.get(id=id)
                            instance.status = False
                            instance.save()
                            response_data.append(ScenceStepSerializer(instance).data)

                        elif type == 'delete':
                            # 递归处理children，确保先删除子节点
                            children = item.get('children', [])
                            if children:
                                process_children(children)

                            # 删除TaskScenceStep关联表数据
                            if lord_id:
                                TaskScenceStep.objects.filter(id=lord_id).delete()

                            # 删除 TaskStep 数据
                            if id:
                                TaskStep.objects.filter(id=id).delete()

                        else:
                            return Response({'message': 'type参数错误'}, status=status.HTTP_400_BAD_REQUEST)

                    # 递归处理children
                    children = item.get('children', [])
                    if children:
                        process_children(children)

            # 调用递归函数处理数据
            process_children(data)

            return Response(response_data, status=status.HTTP_200_OK)

        except Exception as e:
            return Response({'message': str(e)}, status=status.HTTP_400_BAD_REQUEST)